package cqrtplm.vo.query;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Pattern;

public class AdvancedQueryValidator {

    // 允许的操作符白名单
    private static final Set<String> ALLOWED_OPERATORS = new HashSet<>(Arrays.asList(
            "=", "!=", "<", ">", "<=", ">=",
            "LIKE", "NOT LIKE",
            "IN", "NOT IN",
            "IS NULL", "IS NOT NULL",
            "BETWEEN"
    ));

    // 允许的排序方向
    private static final Set<String> ALLOWED_SORT_DIRECTIONS = new HashSet<>(Arrays.asList(
            "ASC", "DESC"
    ));

    // SQL注入检测正则表达式
    private static final Pattern SQL_INJECTION_PATTERN = Pattern.compile(
            "(?i).*\\b(UNION|SELECT|INSERT|DELETE|UPDATE|DROP|ALTER|CREATE|EXEC|XP_|--|;|/\\*|\\*/|\\*|\\bOR\\b|\\bAND\\b|\\bWHERE\\b)\\b.*"
    );

    // 字段名验证正则（字母、数字、下划线）
    private static final Pattern FIELD_NAME_PATTERN = Pattern.compile("^[a-zA-Z_][a-zA-Z0-9_]*$");

    // 表别名验证正则
    private static final Pattern TABLE_ALIAS_PATTERN = Pattern.compile("^[a-zA-Z_][a-zA-Z0-9_]*$");

    // 表名验证正则（允许点号用于schema.table格式）
    private static final Pattern TABLE_NAME_PATTERN = Pattern.compile("^[a-zA-Z_][a-zA-Z0-9_]*(\\.[a-zA-Z_][a-zA-Z0-9_]*)?$");

    /**
     * 验证操作符是否合法
     */
    public static boolean isValidOperator(String operator) {
        return operator != null && ALLOWED_OPERATORS.contains(operator.toUpperCase());
    }

    /**
     * 验证排序方向是否合法
     */
    public static boolean isValidSortDirection(String direction) {
        return direction != null && ALLOWED_SORT_DIRECTIONS.contains(direction.toUpperCase());
    }

    /**
     * 验证字段名是否合法
     */
    public static boolean isValidFieldName(String fieldName) {
        if (fieldName == null || fieldName.trim().isEmpty()) {
            return false;
        }
        return FIELD_NAME_PATTERN.matcher(fieldName).matches();
    }

    /**
     * 验证表别名是否合法
     */
    public static boolean isValidTableAlias(String alias) {
        if (alias == null || alias.trim().isEmpty()) {
            return true; // 别名可为空
        }
        return TABLE_ALIAS_PATTERN.matcher(alias).matches();
    }

    /**
     * 验证表名是否合法
     */
    public static boolean isValidTableName(String tableName) {
        if (tableName == null || tableName.trim().isEmpty()) {
            return false;
        }
        return TABLE_NAME_PATTERN.matcher(tableName).matches();
    }

    /**
     * 检测SQL注入攻击
     */
    public static boolean containsSqlInjection(String input) {
        if (input == null) return false;
        return SQL_INJECTION_PATTERN.matcher(input).matches();
    }

    /**
     * 清理字符串，防止SQL注入
     */
    public static String sanitizeString(String input) {
        if (input == null) return null;
        // 移除可能危险的字符
        return input.replaceAll("[';\\-\\*#\\$\\^\\&\\|<>]", "");
    }

    /**
     * 验证LIKE操作的值（防止通配符滥用）
     */
    public static boolean isValidLikeValue(String value) {
        if (value == null) return false;

        // 防止过多的通配符
        int wildcardCount = 0;
        for (char c : value.toCharArray()) {
            if (c == '%' || c == '_') {
                wildcardCount++;
                if (wildcardCount > 5) {
                    return false;
                }
            }
        }

        return !containsSqlInjection(value);
    }
}
